package eu.fishcode.android.utils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.logging.Level;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

public class BootAnimationZip {

	private static void add(ZipOutputStream zout, File fileSource, String path) {

		final File[] files = fileSource.listFiles();

		for (final File file : files) {
			if (file.isDirectory()) {
				add(zout, file, path + file.getName() + Utils.FileSeparator);
				continue;
			}

			try {
				Utils.logger.log(Level.INFO, "zipping file " + file.getName());

				final byte[] buffer = new byte[1024];

				final FileInputStream fin = new FileInputStream(file);

				zout.putNextEntry(new ZipEntry(path + file.getName()));

				int length;

				while ((length = fin.read(buffer)) > 0) {
					zout.write(buffer, 0, length);
				}

				zout.closeEntry();

				fin.close();

			} catch (final Exception e) {
				Utils.logger.log(Level.SEVERE,
						"zip file failed " + fileSource.getName(), e);
			}
		}

	}

	public static void delete(String sourceZip) {
		Utils.logger.log(Level.INFO, "delete file " + sourceZip);
		final File fileZip = new File(sourceZip);
		if (!fileZip.delete()) {
			Utils.logger.log(Level.SEVERE, "delete file failed " + sourceZip);
		}
	}

	public static ArrayList<String[]> getDescription(String descFile) {
		Utils.logger.log(Level.INFO, "read file " + descFile);
		final ArrayList<String[]> list = new ArrayList<String[]>();
		try {
			final FileReader fr = new FileReader(descFile);
			final BufferedReader br = new BufferedReader(fr);
			String s;
			while ((s = br.readLine()) != null) {
				if (s.trim().equals("")) {
					continue;
				}
				list.add(s.split(" "));
			}
			br.close();
			fr.close();
		} catch (final Exception e) {
			Utils.logger.log(Level.SEVERE, "read file failed " + descFile, e);
			if (list.size() == 0) {
				list.add(new String[] { "0", "0", "0" });
			}
		}
		return list;
	}

	public static void open(String sourceZip, String destinationPath) {
		Utils.logger.log(Level.INFO, "unzip file " + sourceZip + " in "
				+ destinationPath);
		try {
			final File fSourceZip = new File(sourceZip);

			final File temp = new File(destinationPath);
			temp.mkdir();

			final ZipFile zipFile = new ZipFile(fSourceZip);
			final Enumeration<? extends ZipEntry> e = zipFile.entries();

			while (e.hasMoreElements()) {
				final ZipEntry entry = e.nextElement();
				final File destinationFilePath = new File(destinationPath,
						entry.getName());
				Utils.logger.log(Level.INFO,
						"unzipping file " + entry.getName());
				destinationFilePath.getParentFile().mkdirs();

				if (entry.isDirectory()) {
					continue;
				} else {

					final BufferedInputStream bis = new BufferedInputStream(
							zipFile.getInputStream(entry));

					int b;
					final byte buffer[] = new byte[1024];

					final FileOutputStream fos = new FileOutputStream(
							destinationFilePath);
					final BufferedOutputStream bos = new BufferedOutputStream(
							fos, 1024);

					while ((b = bis.read(buffer, 0, 1024)) != -1) {
						bos.write(buffer, 0, b);
					}

					bos.flush();
					bos.close();

					bis.close();
				}
			}
		} catch (final Exception e) {
			Utils.logger.log(Level.SEVERE, "unzip file failed " + sourceZip, e);
		}

	}

	public static void save(String sourcePath, String destinationZip) {
		Utils.logger.log(Level.INFO, "zip file " + sourcePath + " in "
				+ destinationZip);

		try {
			final FileOutputStream fout = new FileOutputStream(destinationZip);
			final ZipOutputStream zout = new ZipOutputStream(fout);
			final File fileSource = new File(sourcePath);

			zout.setMethod(ZipOutputStream.DEFLATED);
			zout.setLevel(0);
			add(zout, fileSource, "");

			zout.close();

		} catch (final Exception e) {
			Utils.logger.log(Level.SEVERE, "zip file failed " + destinationZip,
					e);
		}
	}

	public static void setDescription(String descFile, ArrayList<String[]> desc) {
		Utils.logger.log(Level.INFO, "write file " + descFile);

		try {
			final FileWriter fw = new FileWriter(descFile);
			final BufferedWriter bw = new BufferedWriter(fw);

			for (final String[] info : desc) {

				final String line = Arrays.toString(info).replace(",", "")
						.replaceAll("[\\[\\]]", "");
				bw.write(line + "\n");
			}
			bw.close();
			fw.close();
		} catch (final Exception e) {
			Utils.logger.log(Level.SEVERE, "write file failed " + descFile, e);
		}
	}

}
